package samsung.sds.system.security.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Service;

import samsung.sds.system.security.service.SecurityManagerService;

@Service("sysInvocationSecurityMetadataSourceService")
public class SysInvocationSecurityMetadataSourceService implements
		FilterInvocationSecurityMetadataSource {

	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
	
	private SecurityManagerService securityManagerService;
	
	public SysInvocationSecurityMetadataSourceService(){
		
	}
	
	public SysInvocationSecurityMetadataSourceService(SecurityManagerService securityManagerService) throws Exception{
		this.securityManagerService = securityManagerService;
		getRoleTOResDatas();
	}
	
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		HttpServletRequest request = ((FilterInvocation) object).getRequest(); 
		Collection<ConfigAttribute> rlt = new ArrayList<ConfigAttribute>();
		/**
		 * 若URL命中多个规则，则任何一个规则中定义的角色都可访问此URL
		 */
		for(String keyUrl : resourceMap.keySet()){
			RequestMatcher pathMatcher = new AntPathRequestMatcher(keyUrl);
			if (pathMatcher.matches(request)) {				
				rlt.addAll(resourceMap.get(keyUrl));
			}
		}
		return rlt;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return new ArrayList<ConfigAttribute>();  
	}

	public boolean supports(Class<?> clazz) {
		return true;
	}
	
	private void getRoleTOResDatas() throws Exception{
		updateResourceMap(this.securityManagerService);
	}
	
	/**
	 * 实时更新资源角色对应关系
	 * @param securityManagerService
	 */
	public void updateResourceMap(SecurityManagerService securityManagerService){
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		List<Map<String,String>> list = securityManagerService.getRoleResList();
		if(list != null && list.size() > 0){
			for(Map<String,String> map : list){
				String url = map.get("resUrl");
				String role = map.get("roleName");
				if(!url.trim().equals("/*")){
					if(resourceMap.containsKey(url)){
						resourceMap.get(url).add(new SecurityConfig(role));
					}else{
						Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
						configAttributes.add(new SecurityConfig(role)); 
						resourceMap.put(url, configAttributes); 
					}
				}
			}
		}
	}
	/**
	 * 将新增加的资源访问规则添加至静态映射区
	 * @param url
	 * @param role
	 */
	public static void addResRuleToResourceMap(String url, String role){
		if(resourceMap.containsKey(url)){
			resourceMap.get(url).add(new SecurityConfig(role));
		}else{
			Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
			configAttributes.add(new SecurityConfig(role)); 
			resourceMap.put(url, configAttributes); 
		}
	}
	

	/**
	 * 将资源访问规则从静态映射区去除
	 * @param url
	 * @param role
	 */
	public static void removeResRuleToResourceMap(String url, String role){
		if(resourceMap.containsKey(url)){
			resourceMap.get(url).remove(new SecurityConfig(role));
		}
	}
	
	/**
	 * 将资源访问规则从静态映射区去除
	 * @param url
	 * @param role
	 */
	public static void removeResRuleToResourceMap(String url){
		if(resourceMap.containsKey(url)){
			resourceMap.remove(url);
		}
	}
	


}
